﻿Public Class Oscilator

    Private Frequency As Single = 261.626
    Private SampleIndex As Long = 0
    Private SampleRate As Integer = 44100

    Public OutputAudioStream As AudioStream

    Private Function GenerateSample() As Int16

        Dim SamplesPerCycle As Double = SampleRate / Frequency
        Dim RotationPercent As Double = (SampleIndex Mod SamplesPerCycle) / SamplesPerCycle
        Dim RotationRadians As Double = RotationPercent * Math.PI * 2
        ' 16-bit samples are stored as 2's-complement signed integers, ranging from -32768 to 32767
        Dim SampleValue As Int16 = Math.Sin(RotationRadians) * Int16.MaxValue

        OutputAudioStream.WriteSample(SampleValue)

        SampleIndex += 1

        Frequency *= 1 / 1.000001

    End Function

    Private Sub Start()

        Dim StartTime As Date = Now
        Dim SafetyMargin As Integer = 1000

        Do
            Dim SamplesNeeded As Long = Now.Subtract(StartTime).TotalMilliseconds / 1000 * SampleRate
            If SampleIndex < SamplesNeeded + SafetyMargin Then
                GenerateSample()
            End If

            If Now.Subtract(StartTime).TotalSeconds > 5 Then
                Exit Sub ' stop generating after 30 seconds
            End If

        Loop

    End Sub

    Public Sub New(ByVal OutputStream As AudioStream)
        Me.OutputAudioStream = OutputStream
        Dim NewThread As New System.Threading.Thread(AddressOf Start)
        NewThread.Start()
    End Sub


End Class
